#include "QbLogger.h"

#include <QFile>

#include "log/easylogging++.h"

void rollCallBack(const char* fileName, std::size_t) {
  // TODO:检测
  QString filePath = QString::fromStdString(fileName);
  QFile file(filePath);
  QString newFilePath = filePath.left(filePath.length() - 3);
  for (int i = 0; i < 1000; ++i) {
    QString cpPath = newFilePath + QString::number(i) + ".log";
    if (file.copy(cpPath)) break;
  }
}

class LoggerInitializer {
 public:
  LoggerInitializer() {
    initializeLog();
    el::Configurations conf("./config/log.conf");
    el::Loggers::reconfigureAllLoggers(conf);
    el::Helpers::installPreRollOutCallback(&rollCallBack);
  }
};

inline el::Level loggerLevel(LogLevel l) {
  switch (l) {
    case LogLevel::Trace:
      return el::Level::Trace;
      break;
    case LogLevel::Debug:
      return el::Level::Debug;
      break;
    case LogLevel::Info:
      return el::Level::Info;
      break;
    case LogLevel::Warning:
      return el::Level::Warning;
      break;
    case LogLevel::Error:
      return el::Level::Error;
      break;
    case LogLevel::Fatal:
      return el::Level::Fatal;
      break;
    default:
      return el::Level::Global;
      break;
  }

  return el::Level::Global;
}

static std::string getFormatedMsg(const char* msgfmt, va_list ap) {
  const int maxLen = 2048;
  char tmpInfo[maxLen];
  memset(tmpInfo, 0, maxLen);

#ifdef _MSC_VER
  int ret = vsnprintf_s(tmpInfo, maxLen - 1, msgfmt, ap);
#else
  int ret = vsnprintf(tmpInfo, maxLen - 1, msgfmt, ap);
#endif
  return tmpInfo;
}

void qb_log(LogLevel level, const char* file, const char* function, int line,
            const char* msgfmt, ...) {
  static LoggerInitializer s_li;
  el::base::Writer writer(loggerLevel(level), file, line, function);
  writer.construct(1, el::base::consts::kDefaultLoggerId);
  if (!writer.processed()) return;

  va_list ap;
  va_start(ap, msgfmt);
  writer << getFormatedMsg(msgfmt, ap);
  va_end(ap);
}